package com.ruoyi.system.service.impl;

import java.text.SimpleDateFormat;
import java.util.*;

import com.ruoyi.common.constant.DictConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.SearchResultMapper;
import com.ruoyi.system.service.ISearchResultService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;

/**
 * 检索结果Service业务层处理
 *
 * @author ruoyi
 * @date 2024-08-22
 */
@Service
public class SearchResultServiceImpl implements ISearchResultService {
    @Autowired
    private SearchResultMapper searchResultMapper;

    @Autowired
    private SearchRuleServiceImpl searchRuleService;

    @Autowired
    private SearchWordExcludeServiceImpl searchWordExcludeService;

    /**
     * 查询检索结果
     *
     * @param id 检索结果主键
     * @return 检索结果
     */
    @Override
    public SearchResult selectSearchResultById(Long id) {
        return searchResultMapper.selectSearchResultById(id);
    }

    /**
     * 查询检索结果列表
     *
     * @param searchResult 检索结果
     * @return 检索结果
     */
    @Override
    public List<SearchResult> selectSearchResultList(SearchResult searchResult) {
        return searchResultMapper.selectSearchResultList(searchResult);
    }

    /**
     * 新增检索结果
     *
     * @param searchResult 检索结果
     * @return 结果
     */
    @Override
    public int insertSearchResult(SearchResult searchResult) {
        return searchResultMapper.insertSearchResult(searchResult);
    }

    /**
     * 修改检索结果
     *
     * @param searchResult 检索结果
     * @return 结果
     */
    @Override
    public int updateSearchResult(SearchResult searchResult) {
        return searchResultMapper.updateSearchResult(searchResult);
    }

    /**
     * 批量删除检索结果
     *
     * @param ids 需要删除的检索结果主键
     * @return 结果
     */
    @Override
    public int deleteSearchResultByIds(String ids) {
        return searchResultMapper.deleteSearchResultByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除检索结果信息
     *
     * @param id 检索结果主键
     * @return 结果
     */
    @Override
    public int deleteSearchResultById(Long id) {
        return searchResultMapper.deleteSearchResultById(id);
    }

    public int deleteAll() {
        return searchResultMapper.deleteAll();
    }

    public int deleteByRuleId(Long ruleId) {
        return searchResultMapper.deleteByRuleId(ruleId);
    }

    @Override
    @Transactional
    public boolean fullSearch() {
        //remove all result
        deleteAll();

        //search all enabled rule
        SearchRule spSearchRule = new SearchRule();
        spSearchRule.setStatus(UserConstants.DICT_NORMAL);
        List<SearchRule> searchRuleList = searchRuleService.selectSearchRuleList(spSearchRule);
        for (SearchRule searchRule : searchRuleList) {
            executeSearchRule(searchRule);
        }

        return true;
    }

    public void executeSearchRule(SearchRule searchRule) {
        //remove result
        deleteByRuleId(searchRule.getId());

        //search conditions
        SearchResult spSearchResult = new SearchResult();
        spSearchResult.setRuleId(searchRule.getId());

        //exclude word
        SearchWordExclude spSearchWordExclude = new SearchWordExclude();
        spSearchWordExclude.setStatus(UserConstants.DICT_NORMAL);
        List<SearchWordExclude> exWordList = searchWordExcludeService.selectSearchWordExcludeList(spSearchWordExclude);
        for (SearchWordExclude searchWordExclude : exWordList) {
            if (StringUtils.isEmpty(searchWordExclude.getExWord())) {
                continue;
            }
            String[] exWords = Convert.toStrArray(searchWordExclude.getExWord());
            if (StringUtils.isEmpty(searchWordExclude.getSearchField())) {
                spSearchResult.addExWordContent(exWords);
                spSearchResult.addExWordCompleteFeedback(exWords);
                spSearchResult.addExWordEndFeedback(exWords);
            } else if (DictConstants.search_field_evt_contents.equals(searchWordExclude.getSearchField())) {
                spSearchResult.addExWordContent(exWords);
            } else if (DictConstants.search_field_complete_feedback.equals(searchWordExclude.getSearchField())) {
                spSearchResult.addExWordCompleteFeedback(exWords);
            } else if (DictConstants.search_field_end_feedback.equals(searchWordExclude.getSearchField())) {
                spSearchResult.addExWordEndFeedback(exWords);
            }
        }

        //search rule
        spSearchResult.setEvtTypeId1(searchRule.getEvtTypeId1());
        spSearchResult.setEvtTypeId2(searchRule.getEvtTypeId2());
        spSearchResult.setEvtTypeId3(searchRule.getEvtTypeId3());
        if (StringUtils.isNotEmpty(searchRule.getWordToSearch())) {
            String[] words = Convert.toStrArray(searchRule.getWordToSearch());
            spSearchResult.addWordToSearch(words);
        }

        //do search
        searchResultMapper.insertSearchResultBySearchRule(spSearchResult);
    }

    @Override
    public Map selectEchartsSearchResultDataset(String type, String period) {
        Map map = new HashMap();

        EchartsDataset dataset = new EchartsDataset();
        List<Map> series = new ArrayList<>();

        List<String> allRuleNameList = null;
        //dimensions
        List<String> dimensions = new ArrayList<>();
        dimensions.add("product");
        if ("rule_name".equals(type)) {
            SearchRule spSearchRule = new SearchRule();
            spSearchRule.setStatus(UserConstants.NORMAL);
            allRuleNameList = searchRuleService.selectUniqueRuleNameList(spSearchRule);
            for (String ruleName : allRuleNameList) {
                dimensions.add(ruleName);
                Map serie = new HashMap();
                serie.put("type", "bar");
                serie.put("barGap", 0);
                series.add(serie);
            }
        } else {
            dimensions.add("总量");
            Map serie = new HashMap();
            serie.put("type", "bar");
            serie.put("barGap", 0);
            series.add(serie);
        }
        dataset.setDimensions(dimensions);

        //查询数据
        Map spMap = new HashMap();
        if ("rule_name".equals(type)) {
            //按事件类型
            spMap.put("groupByRuleName", "1");
        }
        if ("day".equals(period)) {
            //日--最近30日
            spMap.put("groupByReportTimeFormat", "%m月%d日");
            spMap.put("reportTimeStart", new SimpleDateFormat("yyyy-MM-dd").format(DateUtils.addDays(new Date(), -30)));
        } else if ("month".equals(period)) {
            //月-最近一年
            spMap.put("groupByReportTimeFormat", "%y年%m月");
            spMap.put("reportTimeStart", new SimpleDateFormat("yyyy-MM-dd").format(DateUtils.setDays(DateUtils.addYears(new Date(), -1), 1)));
        } else if ("year".equals(period)) {
            //年，10年前
            spMap.put("groupByReportTimeFormat", "%y年");
            spMap.put("reportTimeStart", new SimpleDateFormat("yyyy-MM-dd").format(DateUtils.setMonths(DateUtils.setDays(DateUtils.addYears(new Date(), -10), 1), 0)));
        }
        List<Map> lst = searchResultMapper.selectEchartsDataset(spMap);

        //source
        List<Map> source = new ArrayList<>();
        if ("day".equals(period)) {
            //日--最近30日
            for (int i = 30; i >= 0; i--) {
                Map m = new HashMap<>();
                String dtStr = new SimpleDateFormat("MM月dd日").format(DateUtils.addDays(new Date(), -i));
                m.put("product", dtStr);
                if ("rule_name".equals(type)) {
                    for (String ruleName : allRuleNameList) {
                        int cnt = getCnt(lst, dtStr, ruleName);
                        m.put(ruleName, cnt);
                    }
                } else {
                    int cnt = getCnt(lst, dtStr, null);
                    m.put("总量", cnt);
                }
                source.add(m);
            }
        } else if ("month".equals(period)) {
            //月-最近一年
            for (int i = 12; i >= 0; i--) {
                Map m = new HashMap<>();
                String dtStr = new SimpleDateFormat("yy年MM月").format(DateUtils.addMonths(new Date(), -i));
                m.put("product", dtStr);
                if ("rule_name".equals(type)) {
                    for (String ruleName : allRuleNameList) {
                        int cnt = getCnt(lst, dtStr, ruleName);
                        m.put(ruleName, cnt);
                    }
                } else {
                    int cnt = getCnt(lst, dtStr, null);
                    m.put("总量", cnt);
                }
                source.add(m);
            }
        } else if ("year".equals(period)) {
            //月-最近一年
            for (int i = 10; i >= 0; i--) {
                Map m = new HashMap<>();
                String dtStr = new SimpleDateFormat("yy年").format(DateUtils.addYears(new Date(), -i));
                m.put("product", dtStr);
                if ("rule_name".equals(type)) {
                    for (String ruleName : allRuleNameList) {
                        int cnt = getCnt(lst, dtStr, ruleName);
                        m.put(ruleName, cnt);
                    }
                } else {
                    int cnt = getCnt(lst, dtStr, null);
                    m.put("总量", cnt);
                }
                source.add(m);
            }
        }
        dataset.setSource(source);

        map.put("dataset", dataset);
        map.put("series", series);

        return map;
    }

    private int getCnt(List<Map> lst, String dtStr, String ruleName) {
        for (Map map : lst) {
            if (dtStr.equals(map.get("dt")) && (StringUtils.isEmpty(ruleName) || ruleName.equals(map.get("ruleName").toString()))) {
                return Integer.valueOf(map.get("cnt").toString());
            }
        }
        return 0;
    }
}
